#include "TCPListenThread.h"
#include "common.h"
#include "global.h"
#include "messagePickUp.h"
#include "networkessential.h"
#include "TCPRecvThread.h"
#include "messagetype.h"
#include <process.h>
#include "global.h"

#include <iostream>
using namespace std;

bool TCPListenThread::m_isrunning = false;

TCPListenThread::TCPListenThread()
:m_member_center(NULL)
{}

TCPListenThread::TCPListenThread(memberCenter *member_center,
	groupCenter *group_center)
:m_member_center(member_center),
 m_group_center(group_center)
{}

TCPListenThread::~TCPListenThread()
{
	m_isrunning = false;
}

void TCPListenThread::init(memberCenter *member_center,
	groupCenter *group_center)
{
	m_member_center = member_center;
	m_group_center  = group_center;
}

UINT TCPListenThread::threadWork()
{
	if (m_isrunning)
		return -1;
	if (m_member_center == NULL)
		return -2;

	m_isrunning = true;

	int retval;

	// Create a local socket to listen
	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET)
		return -3;
	TCPListenSock = sock;

	// Local address
	sockaddr_in localaddr;
	memset(&localaddr, 0, sizeof(localaddr));
	localaddr.sin_family = AF_INET;
	localaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	localaddr.sin_port = htons(TCPListenPort);

	// Bind the socket with the address
	retval = bind(sock, (sockaddr *) &localaddr, sizeof(localaddr));
	if (retval != 0)
		return -4;

	// Listen
	retval = listen(sock, SOMAXCONN);
	if (retval != 0)
		return -5;

	// Accept
	while (true)
	{
		cout << "TCP accepting! " << endl;
		cout << "===========================================================" << endl;
		singleMember *retp;
		SOCKET clientsock;
		struct sockaddr_in clientaddr;
		int socklen = sizeof(sockaddr_in);
		clientsock = accept(sock, (struct sockaddr *) &clientaddr, &socklen);

		if (clientsock == INVALID_SOCKET)
		{
			closesocket(sock);
			return -6;
		}

		cout << "TCP Connect form: " << inet_ntoa(clientaddr.sin_addr) << endl;

		// Now we start receiving the client information which is used to create a singleMember object
		unsigned int messagetype;
		int message_len;
		if ((messagetype =  RecvFourBytesFromNet<int> (clientsock)) == 0)
			continue;
		if ((message_len =  RecvFourBytesFromNet<int> (clientsock)) == 0)
			continue;

		cout << "Receive form Tcp !" << endl;
		cout << "Type of message : " << messagetype << endl;
		cout << "Length of message : " << message_len << endl;

		char *buf = new char[message_len + 1];
		memset(buf, 0, message_len + 1);
		if (!recvData(clientsock, buf, message_len))
			continue;

		std::string sendername;
		messagePickUp infopick(buf);
		
		infopick.pickUpInfo(sendername);

		cout << "Message form : " << sendername << endl;
		EnterCriticalSection(&globalcs);
		bool ex = m_member_center->isMemberExisted(sendername);
		LeaveCriticalSection(&globalcs);

		if (ex)
			continue;

		// Now create a singleMember object
		EnterCriticalSection(&globalcs);
		retp = m_member_center->createMember(sendername, clientaddr.sin_addr.S_un.S_addr, clientsock);
		LeaveCriticalSection(&globalcs);

		// The object exists, close the socket
		if (retp == NULL)
			closesocket(clientsock);
		else
		{
			TCPRecvThread *tempThread = new TCPRecvThread(retp, m_group_center, m_member_center);
			tempThread->start();
			cout << "TCPRecvThread start !" << endl;
		}

		delete buf;
		cout << "===========================================================" << endl;
		cout << endl;
	}
}
